class Instruction:
    """Represents a unit of change of the state of CPU and memory."""

    opcode = None
    """integer uniquely identifying the instruction"""

    mnemonic = None
    """very short (usually 3-letter) abbreviation of the instruction name"""

    name = None
    """A short phrase (e.g. "Add with carry") describing the instruction"""

    @classmethod
    def execute(cls,cpu,*args,**kwargs):
        """Executes the instruction on specified CPU with specified arguments."""
        raise NotImplementedError

class InstructionSet:
    """Represents set of instructions."""

    def __init__(self,instructions):
        """instructions - list of instructions"""
        self.instructions = {}
        # build opcode -> instruction dictionary
        for instruction in instructions:
            self.instructions[instruction.opcode] = instruction

    def __getitem__(self,key):
        return self.instructions.__getitem__(key)

    def __setitem__(self,key,value):
        self.instructions.__setitem__(key,value)

    def __delitem__(self,key):
        self.instructions.__delitem__(key)
